Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement fallback handler for */resolve requests #4478

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

fendor
Copy link
Collaborator

@fendor fendor commented Jan 6, 2025

We had multiple reports, where resolve requests (such as completion/resolve and codeAction/resolve) are rejected by HLS since the _data_ field of the respective LSP feature has not been populated by HLS.
This makes sense, as we only support resolve for certain kinds of CodeAction/Completions, when they contain particularly expensive properties, such as documentation or non-local type signatures.

So what to do? We can see two options:

  1. Be dumb and permissive: if no plugin wants to resolve a request, then just respond positively with the original item! Potentially this masks real issues, but may not be too bad. If a plugin thinks it can handle the request but it then fails to resolve it, we should still return a failure.
  2. Try and be smart: we try to figure out requests that we're "supposed" to resolve (e.g. those with a data field), and fail if no plugin wants to handle those. This is possible since we set data. So as long as we maintain the invariant that only things which need resolving get data, then it could be okay.

In 'fallbackResolveHandler', we implement the option (2).

Supersedes #4463 and presumably fixes #4451 and #4467

@fendor fendor requested a review from wz1000 as a code owner January 6, 2025 16:36
@fendor fendor requested review from joyfulmantis and michaelpj and removed request for wz1000 and joyfulmantis January 6, 2025 16:36
Comment on lines +304 to +316
SMethod_InlayHintResolve
| noResolveData params -> Just params
SMethod_CompletionItemResolve
| noResolveData params -> Just params
SMethod_CodeActionResolve
| noResolveData params -> Just params
SMethod_WorkspaceSymbolResolve
| noResolveData params -> Just params
SMethod_CodeLensResolve
| noResolveData params -> Just params
SMethod_DocumentLinkResolve
| noResolveData params -> Just params
_ -> Nothing
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pattern matching is bad for long-term maintenance. Anyone an Idea on how to improve this? If we do a string comparison ala isSuffixOf "/resolve" (someMethodToMethodString ...), then I don't see how to actually implement the check, as we need a proof for JL.HasData_ p (Maybe a) where p ~ MessageResult s.

I have an idea for DRY'ing up noResolveData params via Dict, but it introduces a bit of complexity I am not sure is worth it.

Copy link
Collaborator

@soulomoon soulomoon Jan 8, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

noResolveData params via Dict

Sounds interesting, how do we do it

@fendor fendor requested a review from soulomoon January 6, 2025 17:05
Copy link
Collaborator

@soulomoon soulomoon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe some tests?

@fendor fendor force-pushed the enhance/plugins/handle-resolves branch from 788f389 to 75b1191 Compare January 9, 2025 07:05
We had multiple reports, where `resolve` requests (such as
`completion/resolve` and `codeAction/resolve`) are rejected
by HLS since the `_data_` field of the respective LSP feature has not been
populated by HLS.
This makes sense, as we only support `resolve` for certain kinds of
`CodeAction`/`Completions`, when they contain particularly expensive
properties, such as documentation or non-local type signatures.

So what to do? We can see two options:

1. Be dumb and permissive: if no plugin wants to resolve a request, then
   just respond positively with the original item! Potentially this masks
   real issues, but may not be too bad. If a plugin thinks it can
   handle the request but it then fails to resolve it, we should still return a failure.
2. Try and be smart: we try to figure out requests that we're "supposed" to
   resolve (e.g. those with a data field), and fail if no plugin wants to handle those.
   This is possible since we set data.
   So as long as we maintain the invariant that only things which need resolving get
   data, then it could be okay.

In 'fallbackResolveHandler', we implement the option (2).
@fendor fendor force-pushed the enhance/plugins/handle-resolves branch from 75b1191 to 86eeb5e Compare January 11, 2025 14:02
When resolving CodeActions, CodeLenses or Completions do not have a
_data field but a client tries to resolve those items, HLS used to
reject this request.
To avoid this, we install a fallback handler which returns such items
unmodified.

We add tests to make sure this works as intended.
@fendor
Copy link
Collaborator Author

fendor commented Jan 22, 2025

Added a test for all the resolvable requests that we currently support. Notably, our handlers do not support resolve requests for

  • SMethod_WorkspaceSymbolResolve
  • SMethod_DocumentLinkResolve
  • SMethod_InlayHintResolve

How they are handled is similarly hard-coded in https://github.com/haskell/haskell-language-server/blob/master/hls-plugin-api/src/Ide/Types.hs#L996

I don't want to add more features, so I am just adding tests for the supported request types.

@fendor fendor requested review from soulomoon and drsooch January 22, 2025 10:47
Copy link
Collaborator

@soulomoon soulomoon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look good to me, just a minor problem

ghcide/test/exe/ResolveTests.hs Show resolved Hide resolved
@fendor fendor enabled auto-merge (squash) January 22, 2025 19:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

issues with CompletionItemResolve
2 participants